﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security;
using System.Runtime.InteropServices;

namespace CommonLibrary
{	
	/// <summary>
	/// Provides static security methods used throughout application.
	/// </summary>
	public static class Security
	{	
		/// <summary>
		/// String Extension method.
		/// Converts plain string to SecureString.
		/// </summary>
		/// <param name="plainString">Plain string we want to convert to SecureString.</param>
		/// <returns></returns>
		public static SecureString StringToSecureString(this string plainString)
		{
			if (plainString == null)
			{
				throw new ArgumentNullException(global::CommonLibrary.Messages.Default.TO_SECURE_STRING_NULL_ARGUMENT);
			}

			unsafe
			{
				fixed (char* passwordChars = plainString)
				{
					var securePassword = new SecureString(passwordChars, plainString.Length);
					securePassword.MakeReadOnly();
					return securePassword;
				}
			}
		}
		/// <summary>
		/// Converts secure string to plain string.
		/// Consider all security risks before calling this method.
		/// </summary>
		/// <param name="secureString">Secure string we want to to convert to plain string.</param>
		/// <returns></returns>
		public static string SecureStringToString(this SecureString secureString)
		{
			if (secureString == null)
			{
				throw new ArgumentNullException(global::CommonLibrary.Messages.Default.FROM_SECURE_STRING_NULL_ARGUMENT); 
			}

			IntPtr unmanagedString = IntPtr.Zero;
			try
			{
				unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(secureString);
				return Marshal.PtrToStringUni(unmanagedString);
			}
			catch (Exception e)
			{	
				return null;
			}
			finally
			{
				Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString);
			}
		}
	}
}
